package com.revzone.demo001.PermissionModule.common.shiro;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.revzone.demo001.PermissionModule.mapper.UserMapper;
import com.revzone.demo001.entity.PermissionEntity.User;
import com.revzone.demo001.utils.JwtUtils.JWTUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

/**
 * 自定义 Realm
 */
@Component
public class CustomRealm extends AuthorizingRealm {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    UserMapper userMapper;

    /**
     * 必须重写此方法，不然会报错
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }


    /**
     * 只有当需要检测用户权限的时候才会调用此方法，例如checkRole,checkPermission，@RequiresRoles("admin")之类的
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//        System.out.println("————权限认证————");
        logger.info("————权限认证————");
        String username = JWTUtil.getUsername(principals.toString());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

//        List<User> reUser = userMapper.getReUser(username);
        //需要将 role, permission 封装到 Set 作为 info.setRoles(), info.setStringPermissions() 的参数
        // 设置该用户拥有的角色和权限
        Set<String> roleSet = new HashSet<>();
//        roleSet.add(reUser.get(0).getRoles().get(0).getRoleName());
        roleSet.add("root");
        info.setRoles(roleSet);
//        Map<String, String> rolePermission = userMapper.getRolePermission(username);
//        Set<String> permissionSet = new HashSet<>();
//        permissionSet.add(rolePermission.get("rolename")+rolePermission.get("permission"));
//        permissionSet.add(rolePermission.get("permission"));
//        info.setStringPermissions(permissionSet);
        return info;
    }

    /**
     * 默认使用此方法进行用户名正确与否验证，错误抛出异常即可。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//        System.out.println("————身份认证方法————");
        logger.info("————身份认证————");
        String token = (String) authenticationToken.getCredentials();

        // 解密获得username，用于和数据库进行对比
        String username = JWTUtil.getUsername(token);
        if (username == null || !JWTUtil.verify(token, username)) {
//            throw new AuthenticationException("token失效，请重新登录");
            throw new IncorrectCredentialsException("token失效，请重新登录");
        }

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name",username);
        User user = userMapper.selectOne(wrapper);

        if (user.getPassword() == null) {
//            throw new AuthenticationException("该用户不存在！");
            throw new UnknownAccountException("该用户不存在！");
        }

        if (user.getStatus() == 1) {
//            throw new AuthenticationException("该用户已被封号！");
            throw new LockedAccountException("该用户已被封号！");
        }
        return new SimpleAuthenticationInfo(token, token, "MyRealm");
    }


}
